home *** CD-ROM | disk | FTP | other *** search
/ Introduction to 3D Game …ogramming with DirectX 12 / Introduction-to-3D-Game-Programming-with-DirectX-12.ISO / Code.Textures / Chapter 23 Character Animation / SkinnedMesh / Shaders / Default.hlsl < prev    next >
Text File  |  2016-03-02  |  5KB  |  164 lines

  1. //***************************************************************************************
  2. // Default.hlsl by Frank Luna (C) 2015 All Rights Reserved.
  3. //***************************************************************************************
  4.  
  5. // Defaults for number of lights.
  6. #ifndef NUM_DIR_LIGHTS
  7.     #define NUM_DIR_LIGHTS 3
  8. #endif
  9.  
  10. #ifndef NUM_POINT_LIGHTS
  11.     #define NUM_POINT_LIGHTS 0
  12. #endif
  13.  
  14. #ifndef NUM_SPOT_LIGHTS
  15.     #define NUM_SPOT_LIGHTS 0
  16. #endif
  17.  
  18. // Include common HLSL code.
  19. #include "Common.hlsl"
  20.  
  21. struct VertexIn
  22. {
  23.     float3 PosL    : POSITION;
  24.     float3 NormalL : NORMAL;
  25.     float2 TexC    : TEXCOORD;
  26.     float3 TangentL : TANGENT;
  27. #ifdef SKINNED
  28.     float3 BoneWeights : WEIGHTS;
  29.     uint4 BoneIndices  : BONEINDICES;
  30. #endif
  31. };
  32.  
  33. struct VertexOut
  34. {
  35.     float4 PosH    : SV_POSITION;
  36.     float4 ShadowPosH : POSITION0;
  37.     float4 SsaoPosH   : POSITION1;
  38.     float3 PosW    : POSITION2;
  39.     float3 NormalW : NORMAL;
  40.     float3 TangentW : TANGENT;
  41.     float2 TexC    : TEXCOORD;
  42. };
  43.  
  44. VertexOut VS(VertexIn vin)
  45. {
  46.     VertexOut vout = (VertexOut)0.0f;
  47.  
  48.     // Fetch the material data.
  49.     MaterialData matData = gMaterialData[gMaterialIndex];
  50.     
  51. #ifdef SKINNED
  52.     float weights[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  53.     weights[0] = vin.BoneWeights.x;
  54.     weights[1] = vin.BoneWeights.y;
  55.     weights[2] = vin.BoneWeights.z;
  56.     weights[3] = 1.0f - weights[0] - weights[1] - weights[2];
  57.  
  58.     float3 posL = float3(0.0f, 0.0f, 0.0f);
  59.     float3 normalL = float3(0.0f, 0.0f, 0.0f);
  60.     float3 tangentL = float3(0.0f, 0.0f, 0.0f);
  61.     for(int i = 0; i < 4; ++i)
  62.     {
  63.         // Assume no nonuniform scaling when transforming normals, so 
  64.         // that we do not have to use the inverse-transpose.
  65.  
  66.         posL += weights[i] * mul(float4(vin.PosL, 1.0f), gBoneTransforms[vin.BoneIndices[i]]).xyz;
  67.         normalL += weights[i] * mul(vin.NormalL, (float3x3)gBoneTransforms[vin.BoneIndices[i]]);
  68.         tangentL += weights[i] * mul(vin.TangentL.xyz, (float3x3)gBoneTransforms[vin.BoneIndices[i]]);
  69.     }
  70.  
  71.     vin.PosL = posL;
  72.     vin.NormalL = normalL;
  73.     vin.TangentL.xyz = tangentL;
  74. #endif
  75.  
  76.     // Transform to world space.
  77.     float4 posW = mul(float4(vin.PosL, 1.0f), gWorld);
  78.     vout.PosW = posW.xyz;
  79.  
  80.     // Assumes nonuniform scaling; otherwise, need to use inverse-transpose of world matrix.
  81.     vout.NormalW = mul(vin.NormalL, (float3x3)gWorld);
  82.     
  83.     vout.TangentW = mul(vin.TangentL, (float3x3)gWorld);
  84.  
  85.     // Transform to homogeneous clip space.
  86.     vout.PosH = mul(posW, gViewProj);
  87.  
  88.     // Generate projective tex-coords to project SSAO map onto scene.
  89.     vout.SsaoPosH = mul(posW, gViewProjTex);
  90.     
  91.     // Output vertex attributes for interpolation across triangle.
  92.     float4 texC = mul(float4(vin.TexC, 0.0f, 1.0f), gTexTransform);
  93.     vout.TexC = mul(texC, matData.MatTransform).xy;
  94.  
  95.     // Generate projective tex-coords to project shadow map onto scene.
  96.     vout.ShadowPosH = mul(posW, gShadowTransform);
  97.     
  98.     return vout;
  99. }
  100.  
  101. float4 PS(VertexOut pin) : SV_Target
  102. {
  103.     // Fetch the material data.
  104.     MaterialData matData = gMaterialData[gMaterialIndex];
  105.     float4 diffuseAlbedo = matData.DiffuseAlbedo;
  106.     float3 fresnelR0 = matData.FresnelR0;
  107.     float  roughness = matData.Roughness;
  108.     uint diffuseMapIndex = matData.DiffuseMapIndex;
  109.     uint normalMapIndex = matData.NormalMapIndex;
  110.     
  111.     // Dynamically look up the texture in the array.
  112.     diffuseAlbedo *= gTextureMaps[diffuseMapIndex].Sample(gsamAnisotropicWrap, pin.TexC);
  113.  
  114. #ifdef ALPHA_TEST
  115.     // Discard pixel if texture alpha < 0.1.  We do this test as soon 
  116.     // as possible in the shader so that we can potentially exit the
  117.     // shader early, thereby skipping the rest of the shader code.
  118.     clip(diffuseAlbedo.a - 0.1f);
  119. #endif
  120.  
  121.     // Interpolating normal can unnormalize it, so renormalize it.
  122.     pin.NormalW = normalize(pin.NormalW);
  123.     
  124.     float4 normalMapSample = gTextureMaps[normalMapIndex].Sample(gsamAnisotropicWrap, pin.TexC);
  125.     float3 bumpedNormalW = NormalSampleToWorldSpace(normalMapSample.rgb, pin.NormalW, pin.TangentW);
  126.  
  127.     // Uncomment to turn off normal mapping.
  128.     //bumpedNormalW = pin.NormalW;
  129.  
  130.     // Vector from point being lit to eye. 
  131.     float3 toEyeW = normalize(gEyePosW - pin.PosW);
  132.  
  133.     // Finish texture projection and sample SSAO map.
  134.     pin.SsaoPosH /= pin.SsaoPosH.w;
  135.     float ambientAccess = gSsaoMap.Sample(gsamLinearClamp, pin.SsaoPosH.xy, 0.0f).r;
  136.  
  137.     // Light terms.
  138.     float4 ambient = ambientAccess*gAmbientLight*diffuseAlbedo;
  139.  
  140.     // Only the first light casts a shadow.
  141.     float3 shadowFactor = float3(1.0f, 1.0f, 1.0f);
  142.     shadowFactor[0] = CalcShadowFactor(pin.ShadowPosH);
  143.  
  144.     const float shininess = (1.0f - roughness) * normalMapSample.a;
  145.     Material mat = { diffuseAlbedo, fresnelR0, shininess };
  146.     float4 directLight = ComputeLighting(gLights, mat, pin.PosW,
  147.         bumpedNormalW, toEyeW, shadowFactor);
  148.  
  149.     float4 litColor = ambient + directLight;
  150.  
  151.     // Add in specular reflections.
  152.     float3 r = reflect(-toEyeW, bumpedNormalW);
  153.     float4 reflectionColor = gCubeMap.Sample(gsamLinearWrap, r);
  154.     float3 fresnelFactor = SchlickFresnel(fresnelR0, bumpedNormalW, r);
  155.     litColor.rgb += shininess * fresnelFactor * reflectionColor.rgb;
  156.     
  157.     // Common convention to take alpha from diffuse albedo.
  158.     litColor.a = diffuseAlbedo.a;
  159.  
  160.     return litColor;
  161. }
  162.  
  163.  
  164.